﻿namespace HutongGames.PlayMakerEditor
{
    using HutongGames.PlayMaker;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using UnityEditor;
    using UnityEngine;

    public static class FsmEditorUtility
    {
        private static readonly List<string> actionCategoryList = new List<string>();
        private static readonly List<string> actionCategoryLookup = new List<string>();
        private static readonly Dictionary<System.Type, string> ActionNameLookup = new Dictionary<System.Type, string>();
        private static readonly List<System.Type> actionsList = new List<System.Type>();
        private static Texture lastWatermark;
        private static PlayMakerFSM lastWatermarkFsm;
        private static readonly List<Texture2D> LoadedTextures = new List<Texture2D>();
        private static List<System.Type> objectTypeList;
        private static List<string> scriptList;
        public static string[] StateColorNames = new string[] { "Default", "Blue", "Cyan", "Green", "Yellow", "Orange", "Red", "Purple" };
        private static FsmProperty targetFsmProperty;
        private static FsmVariable targetFsmVariable;
        public static readonly List<string> TemplateCategories = new List<string>();
        public static readonly Dictionary<FsmTemplate, string> TemplateCategoryLookup = new Dictionary<FsmTemplate, string>();
        public static readonly List<FsmTemplate> TemplateList = new List<FsmTemplate>();
        private static readonly Dictionary<object, string> TooltipLookup = new Dictionary<object, string>();
        private static readonly Dictionary<System.Type, string> TypeTooltipLookup = new Dictionary<System.Type, string>();
        private static Dictionary<PlayMakerFSM, Texture> watermarkTextureLookup = new Dictionary<PlayMakerFSM, Texture>();

        public static void AddCategorizedEventMenuItem(ref GenericMenu menu, string category, FsmEvent fsmEvent)
        {
            if (category != "")
            {
                category = category + "/";
            }
            menu.AddItem(new GUIContent(category + fsmEvent.Name), FsmEditor.SelectedTransition.FsmEvent == fsmEvent, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectGlobalEvent), fsmEvent);
        }

        private static void AddTemplateToCategory(FsmTemplate template, string category)
        {
            TemplateCategoryLookup.Add(template, category);
            if (!TemplateCategories.Contains(category))
            {
                TemplateCategories.Add(category);
            }
        }

        public static void BuildActionsList()
        {
            actionsList.Clear();
            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (System.Type type in assembly.GetExportedTypes())
                {
                    if (((typeof(IFsmStateAction).IsAssignableFrom(type) && type.IsClass) && !type.IsAbstract) && (!FsmEditorSettings.HideObsoleteActions || (FsmEditorSettings.HideObsoleteActions && !IsObsolete(type))))
                    {
                        actionsList.Add(type);
                    }
                }
            }
            actionCategoryLookup.Clear();
            actionCategoryList.Clear();
            foreach (System.Type type2 in actionsList)
            {
                string actionCategoryAttribute = GetActionCategoryAttribute(type2);
                actionCategoryLookup.Add(actionCategoryAttribute);
                if (!actionCategoryList.Contains(actionCategoryAttribute))
                {
                    actionCategoryList.Add(actionCategoryAttribute);
                }
            }
            actionCategoryList.Sort();
        }

        public static void BuildObjectTypeList()
        {
            List<System.Type> list = new List<System.Type>();
            list.Add(typeof(UnityEngine.Object));
            objectTypeList = list;
            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (System.Type type in assembly.GetExportedTypes())
                {
                    if (type.IsSubclassOf(typeof(UnityEngine.Object)))
                    {
                        string fullName = type.FullName;
                        if (((fullName != null) && !fullName.Contains("PlayMakerEditor")) && !fullName.Contains("UnityEditor"))
                        {
                            objectTypeList.Add(type);
                        }
                    }
                }
            }
            objectTypeList.Sort(delegate (System.Type o1, System.Type o2) {
                return o1.ToString().CompareTo(o2.ToString());
            });
        }

        public static void BuildScriptList()
        {
            scriptList = new List<string>();
            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (System.Type type in assembly.GetExportedTypes())
                {
                    if (((type.IsSubclassOf(typeof(Component)) && type.IsClass) && (!type.IsAbstract && (type != typeof(Behaviour)))) && (type != typeof(MonoBehaviour)))
                    {
                        scriptList.Add(type.Name);
                    }
                }
            }
            scriptList.Sort();
        }

        public static void BuildTemplateList()
        {
            TemplateList.Clear();
            LoadAllAssetsOfType("FsmTemplate");
            FsmTemplate[] collection = (FsmTemplate[]) Resources.FindObjectsOfTypeAll(typeof(FsmTemplate));
            TemplateList.AddRange(collection);
            TemplateList.Sort(delegate (FsmTemplate x, FsmTemplate y) {
                return string.Compare(x.name, y.name);
            });
            CategorizeTemplates();
        }

        private static void CategorizeTemplates()
        {
            TemplateCategoryLookup.Clear();
            TemplateCategories.Clear();
            foreach (FsmTemplate template in TemplateList)
            {
                if (!string.IsNullOrEmpty(template.name))
                {
                    AddTemplateToCategory(template, template.Category);
                }
            }
        }

        public static bool CommitKeyPressed()
        {
            if ((Event.current.keyCode != KeyCode.Return) && (Event.current.keyCode != KeyCode.KeypadEnter))
            {
                return (Event.current.keyCode == KeyCode.Tab);
            }
            return true;
        }

        public static bool CreateFilePath(string fullFileName)
        {
            string directoryName = Path.GetDirectoryName(fullFileName);
            if (string.IsNullOrEmpty(directoryName))
            {
                Debug.LogError("Invalid path: " + fullFileName);
                return false;
            }
            try
            {
                if (!Directory.Exists(directoryName))
                {
                    Directory.CreateDirectory(directoryName);
                }
            }
            catch (Exception)
            {
                Debug.LogError("Could not create directory: " + directoryName);
                return false;
            }
            return true;
        }

        public static void DestroyLoadedTextures()
        {
            foreach (Texture2D textured in LoadedTextures)
            {
                UnityEngine.Object.DestroyImmediate(textured);
            }
            LoadedTextures.Clear();
        }

        public static void DrawTexture(Rect position, Texture texture, Color tint)
        {
            Color color = GUI.color;
            GUI.color = tint;
            GUI.DrawTexture(position, texture);
            GUI.color = color;
        }

        public static bool EnterKeyPressed()
        {
            if (Event.current.keyCode != KeyCode.Return)
            {
                return (Event.current.keyCode == KeyCode.KeypadEnter);
            }
            return true;
        }

        public static bool EventListContainsEventName(List<FsmEvent> eventList, string fsmEventName)
        {
            foreach (FsmEvent event2 in eventList)
            {
                if (event2.Name == fsmEventName)
                {
                    return true;
                }
            }
            return false;
        }

        public static Fsm FindFsmOnGameObject(GameObject go)
        {
            if (go != null)
            {
                PlayMakerFSM component = go.GetComponent<PlayMakerFSM>();
                if (component != null)
                {
                    return component.Fsm;
                }
            }
            return null;
        }

        public static Fsm FindFsmOnGameObject(GameObject go, string name)
        {
            if (go != null)
            {
                if (string.IsNullOrEmpty(name))
                {
                    name = "FSM";
                }
                foreach (PlayMakerFSM rfsm in go.GetComponents<PlayMakerFSM>())
                {
                    if (rfsm.name == name)
                    {
                        return rfsm.Fsm;
                    }
                }
            }
            return null;
        }

        public static string FormatTime(float time)
        {
            DateTime time2 = new DateTime(Convert.ToInt64((float) (Mathf.Max(time, 0f) * 1E+07f)), DateTimeKind.Unspecified);
            return time2.ToString("mm:ss:ff");
        }

        public static bool FsmHasVariable(Fsm fsm, string name)
        {
            foreach (FsmVariable variable in FsmVariable.GetFsmVariableList(fsm.Variables, null))
            {
                if (variable.Name == name)
                {
                    return true;
                }
            }
            return false;
        }

        private static bool FsmNameExists(IEnumerable<PlayMakerFSM> fsmComponents, string name)
        {
            foreach (PlayMakerFSM rfsm in fsmComponents)
            {
                if (rfsm.Fsm.Name == name)
                {
                    return true;
                }
            }
            return false;
        }

        public static bool FsmRespondsToEvent(Fsm fsm, FsmEvent fsmEvent)
        {
            return (((fsm != null) && !FsmEvent.IsNullOrEmpty(fsmEvent)) && FsmRespondsToEvent(fsm, fsmEvent.Name));
        }

        public static bool FsmRespondsToEvent(Fsm fsm, string fsmEventName)
        {
            if ((fsm != null) && !string.IsNullOrEmpty(fsmEventName))
            {
                foreach (FsmTransition transition in fsm.GlobalTransitions)
                {
                    if (transition.EventName == fsmEventName)
                    {
                        return true;
                    }
                }
                foreach (FsmState state in fsm.States)
                {
                    foreach (FsmTransition transition2 in state.Transitions)
                    {
                        if (transition2.EventName == fsmEventName)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        public static bool FsmStateRespondsToEvent(FsmState state, FsmEvent fsmEvent)
        {
            if (!FsmEvent.IsNullOrEmpty(fsmEvent))
            {
                foreach (FsmTransition transition in state.Fsm.GlobalTransitions)
                {
                    if (transition.EventName == fsmEvent.Name)
                    {
                        return true;
                    }
                }
                foreach (FsmTransition transition2 in state.Transitions)
                {
                    if (transition2.EventName == fsmEvent.Name)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public static bool GameObjectHasFSM(GameObject gameObject)
        {
            if (gameObject != null)
            {
                foreach (PlayMakerFSM rfsm in FsmEditor.FsmComponentList)
                {
                    if (((rfsm != null) && (rfsm.gameObject != null)) && (rfsm.gameObject == gameObject))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public static GenericMenu GenerateObjectTypesMenu(FsmProperty fsmProperty)
        {
            targetFsmProperty = fsmProperty;
            GenericMenu menu = new GenericMenu();
            foreach (System.Type type in ObjectTypeList)
            {
                string fullName = type.FullName;
                if (fullName != null)
                {
                    string text = fullName.Replace(".", "/");
                    menu.AddItem(new GUIContent(text), false, new GenericMenu.MenuFunction2(FsmEditorUtility.SetFsmPropertyTargetType), fullName);
                }
            }
            return menu;
        }

        public static GenericMenu GenerateObjectTypesMenu(FsmVariable fsmVariable)
        {
            targetFsmVariable = fsmVariable;
            GenericMenu menu = new GenericMenu();
            foreach (System.Type type in ObjectTypeList)
            {
                string fullName = type.FullName;
                if (fullName != null)
                {
                    string text = fullName.Replace(".", "/");
                    menu.AddItem(new GUIContent(text), fullName == fsmVariable.TypeName, new GenericMenu.MenuFunction2(FsmEditorUtility.SetFsmVariableTargetType), fullName);
                }
            }
            return menu;
        }

        public static GenericMenu GeneratePropertyMenu(FsmProperty fsmProperty)
        {
            targetFsmProperty = fsmProperty;
            GenericMenu menu = new GenericMenu();
            System.Type type = FsmUtility.GetType(fsmProperty.TargetTypeName);
            if (type != null)
            {
                foreach (MemberInfo info in ReflectionUtils.GetFieldsAndProperties(type, BindingFlags.Public | BindingFlags.Instance))
                {
                    if (IsSupportedParameterType(ReflectionUtils.GetMemberUnderlyingType(info)))
                    {
                        string name = info.Name;
                        if (info.DeclaringType != type)
                        {
                            name = "Inherited/" + name;
                        }
                        menu.AddItem(new GUIContent(name), false, new GenericMenu.MenuFunction2(FsmEditorUtility.SetFsmPropertyName), info.Name);
                    }
                }
            }
            return menu;
        }

        public static string GenerateUniqueFsmName(GameObject go)
        {
            PlayMakerFSM[] components = go.GetComponents<PlayMakerFSM>();
            string name = "FSM";
            int num = 1;
            while (FsmNameExists(components, name))
            {
                num++;
                name = "FSM " + num;
            }
            return name;
        }

        public static string GenerateUniqueLabel(List<string> labels, string label)
        {
            while (labels.Contains(label))
            {
                label = label + " ";
            }
            return label;
        }

        public static string GetActionCategoryAttribute(object[] attributes)
        {
            foreach (object obj2 in attributes)
            {
                ActionCategoryAttribute attribute = obj2 as ActionCategoryAttribute;
                if (attribute != null)
                {
                    return attribute.Category;
                }
            }
            return "Misc";
        }

        public static string GetActionCategoryAttribute(System.Type objType)
        {
            if (objType == null)
            {
                return null;
            }
            return GetActionCategoryAttribute(objType.GetCustomAttributes(true));
        }

        public static int GetActionIndex(FsmState state, FsmStateAction action)
        {
            int num = 0;
            foreach (FsmStateAction action2 in state.Actions)
            {
                if (action2 == action)
                {
                    return num;
                }
                num++;
            }
            return -1;
        }

        public static string GetActionLabel(FsmStateAction action)
        {
            if (action == null)
            {
                return "None (Action)";
            }
            if (string.IsNullOrEmpty(action.Name))
            {
                return GetActionLabel(action.GetType());
            }
            return action.Name;
        }

        public static string GetActionLabel(System.Type actionType)
        {
            string str;
            if (actionType == null)
            {
                return "";
            }
            if (!ActionNameLookup.TryGetValue(actionType, out str))
            {
                str = NicifyVariableName(StripNamespace(actionType.ToString()));
                ActionNameLookup.Add(actionType, str);
            }
            return str;
        }

        public static string GetActionTooltip(FsmStateAction action)
        {
            string str;
            if (TooltipLookup.TryGetValue(action, out str))
            {
                return str;
            }
            return UpdateActionTooltip(action);
        }

        public static string GetCurrentStateLabel(Fsm fsm)
        {
            if (EditorApplication.isPlaying)
            {
                if (fsm.ActiveState != null)
                {
                    return fsm.ActiveState.Name;
                }
                return "No Active State";
            }
            FsmState state = fsm.GetState(fsm.StartState);
            if (state != null)
            {
                return state.Name;
            }
            return "No Start State";
        }

        public static GUIContent GetEventLabel(FsmTransition transition)
        {
            GUIContent content2 = new GUIContent();
            content2.text = "...";
            GUIContent content = content2;
            if (!FsmEvent.IsNullOrEmpty(transition.FsmEvent))
            {
                content.text = transition.FsmEvent.Name;
            }
            return content;
        }

        public static List<FsmEvent> GetEventList(Fsm fsm)
        {
            if (fsm != null)
            {
                return GetGlobalEventList(fsm);
            }
            return GetGlobalEventList();
        }

        public static List<FsmEvent> GetEventList(PlayMakerFSM fsmComponent)
        {
            if (fsmComponent != null)
            {
                return GetGlobalEventList(fsmComponent.Fsm);
            }
            return GetGlobalEventList();
        }

        public static List<FsmEvent> GetEventList(GameObject go)
        {
            return GetGlobalEventList();
        }

        public static GUIContent[] GetEventNamesFromList(List<FsmEvent> eventList)
        {
            List<GUIContent> list2 = new List<GUIContent>();
            list2.Add(new GUIContent("None"));
            List<GUIContent> list = list2;
            foreach (FsmEvent event2 in eventList)
            {
                list.Add(new GUIContent(event2.Name));
            }
            return list.ToArray();
        }

        public static string GetFieldSection(object[] attributes)
        {
            foreach (object obj2 in attributes)
            {
                ActionSection section = obj2 as ActionSection;
                if (section != null)
                {
                    return section.Section;
                }
            }
            return null;
        }

        public static string[] GetFiles(string path, string searchPattern, [Optional, DefaultParameterValue(SearchOption.TopDirectoryOnly)] SearchOption searchOption)
        {
            string[] strArray = searchPattern.Split(new char[] { '|' });
            List<string> list = new List<string>();
            foreach (string str in strArray)
            {
                list.AddRange(Directory.GetFiles(path, str, searchOption));
            }
            list.Sort();
            return list.ToArray();
        }

        public static int GetFsmIndex(Fsm fsm)
        {
            if (((fsm != null) && (fsm.Owner != null)) && (fsm.GameObject != null))
            {
                PlayMakerFSM[] components = fsm.GameObject.GetComponents<PlayMakerFSM>();
                int num = 0;
                foreach (PlayMakerFSM rfsm in components)
                {
                    if (rfsm.Fsm == fsm)
                    {
                        return num;
                    }
                    num++;
                }
            }
            return -1;
        }

        public static string GetFsmLabel(Fsm fsm)
        {
            if (fsm == null)
            {
                return "None (Fsm)";
            }
            int fsmNameIndex = GetFsmNameIndex(fsm);
            if (fsmNameIndex > 0)
            {
                return string.Concat(new object[] { fsm.Name, " (", fsmNameIndex + 1, ")" });
            }
            return fsm.Name;
        }

        public static int GetFsmNameIndex(Fsm fsm)
        {
            if (((fsm != null) && (fsm.Owner != null)) && (fsm.GameObject != null))
            {
                PlayMakerFSM[] components = fsm.GameObject.GetComponents<PlayMakerFSM>();
                int num = 0;
                foreach (PlayMakerFSM rfsm in components)
                {
                    if (rfsm.Fsm == fsm)
                    {
                        return num;
                    }
                    if (rfsm.Fsm.Name == fsm.Name)
                    {
                        num++;
                    }
                }
            }
            return 0;
        }

        public static Fsm GetFsmTarget(Fsm fsm, FsmEventTarget fsmEventTarget)
        {
            if (fsmEventTarget == null)
            {
                return fsm;
            }
            switch (fsmEventTarget.target)
            {
                case FsmEventTarget.EventTarget.Self:
                    return fsm;

                case FsmEventTarget.EventTarget.GameObject:
                    return null;

                case FsmEventTarget.EventTarget.GameObjectFSM:
                    return null;

                case FsmEventTarget.EventTarget.FSMComponent:
                    if (fsmEventTarget.fsmComponent != null)
                    {
                        return fsmEventTarget.fsmComponent.Fsm;
                    }
                    return null;

                case FsmEventTarget.EventTarget.BroadcastAll:
                    return null;
            }
            return null;
        }

        public static string GetFullFsmLabel(Fsm fsm)
        {
            if ((fsm == null) || (fsm.Owner == null))
            {
                return "None (FSM)";
            }
            string str = fsm.OwnerName + " : " + GetFsmLabel(fsm);
            if (FsmEditorSettings.AddPrefabLabel && (EditorUtility.GetPrefabType(fsm.Owner) == PrefabType.Prefab))
            {
                str = str + " (Prefab)";
            }
            return str;
        }

        public static string GetFullFsmLabel(PlayMakerFSM fsmComponent)
        {
            if (fsmComponent != null)
            {
                return GetFullFsmLabel(fsmComponent.Fsm);
            }
            return "None (PlayMakerFSM)";
        }

        public static string GetFullStateLabel(FsmState state)
        {
            if (state == null)
            {
                return "None (State)";
            }
            return (GetFullFsmLabel(state.Fsm) + " : " + state.Name);
        }

        public static Fsm GetGameObjectFSM(FsmGameObject gameObject, FsmString fsmName)
        {
            if (!gameObject.UseVariable && !fsmName.UseVariable)
            {
                if (string.IsNullOrEmpty(fsmName.Value))
                {
                    foreach (Fsm fsm in FsmEditor.FsmList)
                    {
                        if (fsm.GameObject == gameObject.Value)
                        {
                            return fsm;
                        }
                    }
                }
                else
                {
                    foreach (Fsm fsm2 in FsmEditor.FsmList)
                    {
                        if ((fsm2.GameObject == gameObject.Value) && (fsmName.Value == fsm2.Name))
                        {
                            return fsm2;
                        }
                    }
                }
            }
            return null;
        }

        public static List<FsmEvent> GetGlobalEventList()
        {
            List<FsmEvent> list = new List<FsmEvent>();
            foreach (FsmEvent event2 in FsmEvent.EventList)
            {
                if (event2.IsGlobal)
                {
                    list.Add(event2);
                }
            }
            return list;
        }

        public static List<FsmEvent> GetGlobalEventList(Fsm fsm)
        {
            if (fsm == null)
            {
                return GetGlobalEventList();
            }
            List<FsmEvent> list = new List<FsmEvent>();
            foreach (FsmEvent event2 in fsm.Events)
            {
                if (event2.IsGlobal)
                {
                    list.Add(event2);
                }
            }
            return list;
        }

        public static string GetHelpUrlAttribute(object[] attributes)
        {
            foreach (object obj2 in attributes)
            {
                HelpUrlAttribute attribute = obj2 as HelpUrlAttribute;
                if (attribute != null)
                {
                    return attribute.Url;
                }
            }
            return null;
        }

        public static string GetHelpUrlAttribute(System.Type objType)
        {
            if (objType == null)
            {
                return null;
            }
            return GetHelpUrlAttribute(objType.GetCustomAttributes(true));
        }

        public static string GetObsoleteAttribute(System.Type type)
        {
            if (type != null)
            {
                foreach (object obj2 in type.GetCustomAttributes(true))
                {
                    ObsoleteAttribute attribute = obj2 as ObsoleteAttribute;
                    if (attribute != null)
                    {
                        return attribute.Message;
                    }
                }
            }
            return "";
        }

        public static string GetPlayMakerVersionString()
        {
            Version version = Assembly.GetExecutingAssembly().GetName().Version;
            return string.Concat(new object[] { version.Major, ".", version.Minor, ".", version.Build, " (", version.Revision, ")" });
        }

        public static string GetStateLabel(string stateName)
        {
            if (!string.IsNullOrEmpty(stateName))
            {
                return stateName;
            }
            return "None (State)";
        }

        public static string GetTooltipAttribute(object instance)
        {
            if (instance == null)
            {
                return null;
            }
            return GetTooltipAttribute(instance.GetType());
        }

        public static string GetTooltipAttribute(FieldInfo field)
        {
            if (field == null)
            {
                return null;
            }
            return GetTooltipAttribute(field.GetCustomAttributes(true));
        }

        public static string GetTooltipAttribute(System.Type objType)
        {
            if (objType == null)
            {
                return null;
            }
            return GetTooltipAttribute(objType.GetCustomAttributes(true));
        }

        public static string GetTooltipAttribute(object[] attributes)
        {
            foreach (object obj2 in attributes)
            {
                TooltipAttribute attribute = obj2 as TooltipAttribute;
                if (attribute != null)
                {
                    return attribute.Text;
                }
            }
            return string.Empty;
        }

        public static string GetTypeTooltip(System.Type type)
        {
            string str;
            if (!TypeTooltipLookup.TryGetValue(type, out str))
            {
                if (type.IsSubclassOf(typeof(NamedVariable)))
                {
                    str = StripNamespace(type.GetProperty("Value").PropertyType.ToString());
                }
                else
                {
                    str = StripNamespace(type.ToString());
                }
                TypeTooltipLookup.Add(type, NicifyTypeTooltip(str));
            }
            return str;
        }

        public static System.Type GetUIHintVariableType(UIHint hint)
        {
            switch (hint)
            {
                case UIHint.FsmFloat:
                    return typeof(FsmFloat);

                case UIHint.FsmInt:
                    return typeof(FsmInt);

                case UIHint.FsmBool:
                    return typeof(FsmBool);

                case UIHint.FsmString:
                    return typeof(FsmString);

                case UIHint.FsmVector3:
                    return typeof(FsmVector3);

                case UIHint.FsmGameObject:
                    return typeof(FsmGameObject);

                case UIHint.FsmColor:
                    return typeof(FsmColor);

                case UIHint.FsmRect:
                    return typeof(FsmRect);

                case UIHint.FsmMaterial:
                    return typeof(FsmMaterial);

                case UIHint.FsmTexture:
                    return typeof(FsmTexture);

                case UIHint.FsmQuaternion:
                    return typeof(FsmQuaternion);

                case UIHint.FsmObject:
                    return typeof(FsmObject);
            }
            Debug.LogError("Unrecognized variable type: " + hint);
            return null;
        }

        public static string GetWatermarkLabel(PlayMakerFSM fsmComponent, [Optional, DefaultParameterValue("No Watermark")] string defaultLabel)
        {
            if ((fsmComponent != null) && !string.IsNullOrEmpty(fsmComponent.Fsm.Watermark))
            {
                return fsmComponent.Fsm.Watermark;
            }
            return defaultLabel;
        }

        public static string[] GetWatermarkNames()
        {
            string path = Path.Combine(Application.dataPath, "PlayMaker/Editor/Watermarks/");
            if (!Directory.Exists(path))
            {
                Debug.LogError("Missing Watermarks directory: Assets/PlayMaker/Editor/Watermarks");
                return new string[0];
            }
            string[] strArray = GetFiles(path, "*.png|*.jpg|*.jpeg", SearchOption.TopDirectoryOnly);
            for (int i = 0; i < strArray.Length; i++)
            {
                strArray[i] = Path.GetFileName(strArray[i]);
            }
            return strArray;
        }

        public static Texture GetWatermarkTexture(PlayMakerFSM fsmComponent)
        {
            Texture texture;
            if (lastWatermarkFsm == fsmComponent)
            {
                return lastWatermark;
            }
            if ((fsmComponent == null) || string.IsNullOrEmpty(fsmComponent.Fsm.Watermark))
            {
                return null;
            }
            watermarkTextureLookup.TryGetValue(fsmComponent, out texture);
            if (texture != null)
            {
                lastWatermarkFsm = fsmComponent;
                lastWatermark = texture;
                return texture;
            }
            texture = LoadWatermarkTexture(fsmComponent.Fsm.Watermark);
            lastWatermarkFsm = fsmComponent;
            lastWatermark = texture;
            watermarkTextureLookup.Remove(fsmComponent);
            watermarkTextureLookup.Add(fsmComponent, texture);
            return texture;
        }

        public static Texture[] GetWatermarkTextures([Optional, DefaultParameterValue(true)] bool showProgress)
        {
            List<Texture> list = new List<Texture>();
            string path = Path.Combine(Application.dataPath, "PlayMaker/Editor/Watermarks/");
            if (!Directory.Exists(path))
            {
                Debug.LogError("Missing Watermarks directory: Assets/PlayMaker/Editor/Watermarks");
                return new Texture[0];
            }
            string[] strArray = GetFiles(path, "*.png|*.jpg|*.jpeg", SearchOption.TopDirectoryOnly);
            int num = 0;
            float length = strArray.Length;
            foreach (string str2 in strArray)
            {
                if (showProgress)
                {
                    EditorUtility.DisplayProgressBar("PlayMaker", "Loading Watermark Textures...", ((float) num++) / length);
                }
                Texture item = (Texture) AssetDatabase.LoadMainAssetAtPath(str2.Replace(Application.dataPath, "Assets"));
                list.Add(item);
            }
            if (showProgress)
            {
                EditorUtility.ClearProgressBar();
            }
            return list.ToArray();
        }

        public static bool IsModifiedPrefabInstance(Fsm fsm)
        {
            if ((fsm == null) || (fsm.Owner == null))
            {
                return false;
            }
            PrefabType prefabType = EditorUtility.GetPrefabType(fsm.Owner);
            if ((prefabType != PrefabType.PrefabInstance) && (prefabType != PrefabType.ModelPrefabInstance))
            {
                return false;
            }
            SerializedObject obj2 = new SerializedObject(fsm.Owner);
            return obj2.FindProperty("fsm").prefabOverride;
        }

        public static bool IsObsolete(System.Type type)
        {
            if (type == null)
            {
                return true;
            }
            foreach (object obj2 in type.GetCustomAttributes(true))
            {
                if (obj2 is ObsoleteAttribute)
                {
                    return true;
                }
            }
            return false;
        }

        public static bool IsPrefab(Fsm fsm)
        {
            return (((fsm != null) && (fsm.Owner != null)) && (EditorUtility.GetPrefabType(fsm.Owner) == PrefabType.Prefab));
        }

        public static bool IsSupportedParameterType(System.Type parameterType)
        {
            if (((((parameterType != typeof(string)) && (parameterType != typeof(int))) && ((parameterType != typeof(float)) && (parameterType != typeof(Vector3)))) && (((parameterType != typeof(Color)) && (parameterType != typeof(bool))) && ((parameterType != typeof(Quaternion)) && (parameterType != typeof(Material))))) && ((parameterType != typeof(Texture)) && (parameterType != typeof(Rect))))
            {
                return parameterType.IsSubclassOf(typeof(UnityEngine.Object));
            }
            return true;
        }

        private static void LoadAllAssetsOfType(string type)
        {
            HierarchyProperty property = new HierarchyProperty(HierarchyType.Assets);
            property.SetSearchFilter(type, 2);
            while (property.Next(null))
            {
                AssetDatabase.LoadMainAssetAtPath(AssetDatabase.GetAssetPath(property.instanceID));
            }
        }

        public static List<string> LoadAllPrefabsInProject()
        {
            return LoadGameObjectsWithFsmComponent();
        }

        public static Texture2D LoadDllResource(string resourceName, int width, int height)
        {
            Texture2D item = (Texture2D) Resources.Load(resourceName);
            if (item == null)
            {
                item = new Texture2D(width, height, TextureFormat.ARGB32, false);
                Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("HutongGames.PlayMakerEditor.Assets.PlayMaker.Editor.Resources." + resourceName + ".png");
                if (manifestResourceStream != null)
                {
                    item.LoadImage(ReadToEnd(manifestResourceStream));
                    manifestResourceStream.Close();
                }
                else
                {
                    Debug.LogWarning("Missing Dll resource: " + resourceName);
                }
                LoadedTextures.Add(item);
            }
            return item;
        }

        private static List<string> LoadGameObjectsWithFsmComponent()
        {
            List<string> list = new List<string>();
            HierarchyProperty property = new HierarchyProperty(HierarchyType.Assets);
            property.SetSearchFilter("GameObject", 2);
            float num = property.CountRemaining(null);
            float num2 = 0f;
            property.Reset();
            while (property.Next(null))
            {
                num2++;
                EditorUtility.DisplayProgressBar("Loading Prefabs With PlayMakerFSMs...", "NOTE: You can turn this off in preferences.", num2 / num);
                string assetPath = AssetDatabase.GetAssetPath(property.instanceID);
                foreach (string str2 in AssetDatabase.GetDependencies(new string[] { assetPath }))
                {
                    if (str2 == "assets/playmaker/playmaker.dll")
                    {
                        list.Add(assetPath);
                        AssetDatabase.LoadAllAssetsAtPath(assetPath);
                    }
                }
            }
            EditorUtility.ClearProgressBar();
            return list;
        }

        public static void LoadUsedPrefabs()
        {
            foreach (Fsm fsm in FsmEditor.FsmList)
            {
                if ((fsm.Owner != null) && (EditorUtility.GetPrefabType(fsm.Owner) == PrefabType.PrefabInstance))
                {
                    EditorUtility.GetPrefabParent(fsm.Owner);
                }
            }
        }

        public static Texture LoadWatermarkTexture(string name)
        {
            string path = Path.Combine(Application.dataPath, "PlayMaker/Editor/Watermarks/" + name);
            if (!File.Exists(path))
            {
                Debug.LogError("Missing watermark texture: " + path.Replace(Application.dataPath, "Assets"));
                return null;
            }
            Texture texture = (Texture) AssetDatabase.LoadMainAssetAtPath(path.Replace(Application.dataPath, "Assets"));
            if (texture == null)
            {
                Debug.LogError("Failed to load texture: " + path.Replace(Application.dataPath, "Assets"));
            }
            return texture;
        }

        private static string NicifyTypeTooltip(string tooltip)
        {
            string str = tooltip;
            if (str == null)
            {
                return tooltip;
            }
            if (!(str == "Single"))
            {
                if (str == "FsmOwnerDefault")
                {
                    return "GameObject";
                }
                return tooltip;
            }
            return "Float";
        }

        public static string NicifyVariableName(string name)
        {
            return ObjectNames.NicifyVariableName(name).Replace("Vector 3", "Vector3 ").Replace("GUI", "GUI ").Replace("GUI Layout", "GUILayout").Replace("ITween", "iTween").Replace("IPhone", "iPhone").Replace("i Phone", "iPhone").Replace("Player Prefs", "PlayerPrefs").Replace("Network View ", "NetworkView ").Replace("Master Server ", "MasterServer ").Replace("Rpc ", "RPC ");
        }

        public static int PackColorIntoInt(Color color)
        {
            int num = (int) (color.r * 255f);
            int num2 = (int) (color.g * 255f);
            int num3 = (int) (color.b * 255f);
            return (((num << 0x10) | (num2 << 8)) | num3);
        }

        private static byte[] ReadToEnd(Stream stream)
        {
            byte[] buffer4;
            long position = stream.Position;
            stream.Position = 0L;
            try
            {
                int num3;
                byte[] buffer = new byte[0x1000];
                int offset = 0;
                while ((num3 = stream.Read(buffer, offset, buffer.Length - offset)) > 0)
                {
                    offset += num3;
                    if (offset == buffer.Length)
                    {
                        int num4 = stream.ReadByte();
                        if (num4 != -1)
                        {
                            byte[] buffer2 = new byte[buffer.Length * 2];
                            Buffer.BlockCopy(buffer, 0, buffer2, 0, buffer.Length);
                            Buffer.SetByte(buffer2, offset, (byte) num4);
                            buffer = buffer2;
                            offset++;
                        }
                    }
                }
                byte[] dst = buffer;
                if (buffer.Length != offset)
                {
                    dst = new byte[offset];
                    Buffer.BlockCopy(buffer, 0, dst, 0, offset);
                }
                buffer4 = dst;
            }
            finally
            {
                stream.Position = position;
            }
            return buffer4;
        }

        public static void SanityCheckEventList(Fsm fsm)
        {
            bool flag = false;
            List<FsmEvent> fsmEventList = new List<FsmEvent>();
            foreach (FsmEvent event2 in fsm.Events)
            {
                if (!FsmEvent.EventListContainsEvent(fsmEventList, event2.Name))
                {
                    fsmEventList.Add(event2);
                }
                else
                {
                    flag = true;
                    Debug.LogError("Duplicate Event Found: " + event2.Name);
                }
            }
            if (flag)
            {
                fsm.Events = fsmEventList.ToArray();
                FsmEditor.SetFsmDirty(fsm, false, false);
            }
        }

        private static void SetFsmPropertyName(object userdata)
        {
            if (targetFsmProperty != null)
            {
                targetFsmProperty.SetPropertyName(userdata as string);
            }
            FsmEditor.SetFsmDirty(true, false);
            FsmEditor.SaveActions();
        }

        private static void SetFsmPropertyTargetType(object userdata)
        {
            if (targetFsmProperty != null)
            {
                targetFsmProperty.TargetTypeName = userdata as string;
                FsmEditor.SetFsmDirty(true, false);
                FsmEditor.SaveActions();
            }
        }

        private static void SetFsmVariableTargetType(object userdata)
        {
            if (targetFsmVariable != null)
            {
                targetFsmVariable.TypeName = userdata as string;
                targetFsmVariable.ObjectType = FsmUtility.GetType(targetFsmVariable.TypeName);
                targetFsmVariable.UpdateVariableValue();
                FsmEditor.SetFsmDirty(true, false);
                FsmEditor.SaveActions();
            }
        }

        public static Texture SetWatermarkTexture(PlayMakerFSM fsmComponent, string textureName)
        {
            fsmComponent.Fsm.Watermark = textureName;
            watermarkTextureLookup.Remove(fsmComponent);
            lastWatermarkFsm = null;
            return GetWatermarkTexture(fsmComponent);
        }

        public static bool ShouldModify(Fsm fsm)
        {
            if ((fsm == null) || (fsm.Owner == null))
            {
                return false;
            }
            switch (EditorUtility.GetPrefabType(fsm.Owner))
            {
                case PrefabType.None:
                case PrefabType.Prefab:
                case PrefabType.ModelPrefab:
                case PrefabType.MissingPrefabInstance:
                case PrefabType.DisconnectedPrefabInstance:
                case PrefabType.DisconnectedModelPrefabInstance:
                    return true;

                case PrefabType.PrefabInstance:
                case PrefabType.ModelPrefabInstance:
                    return IsModifiedPrefabInstance(fsm);
            }
            return true;
        }

        public static bool StateExistsInPrefabParent(FsmState state)
        {
            PlayMakerFSM owner = state.Fsm.Owner as PlayMakerFSM;
            if (EditorUtility.GetPrefabType(owner) != PrefabType.PrefabInstance)
            {
                return false;
            }
            return true;
        }

        public static string StripNamespace(string name)
        {
            string[] strArray = name.Split(new char[] { Convert.ToChar(".") });
            if (strArray.Length <= 0)
            {
                return name;
            }
            return strArray[strArray.Length - 1];
        }

        public static string StripUnityEngineNamespace(string name)
        {
            if (name.IndexOf("UnityEngine.") != 0)
            {
                return name;
            }
            return name.Replace("UnityEngine.", "");
        }

        public static Color UnpackColorFromInt(int packedValue)
        {
            int num = packedValue >> 0x10;
            int num2 = (packedValue >> 8) & 0xff;
            int num3 = packedValue & 0xff;
            return new Color(((float) num) / 255f, ((float) num2) / 255f, ((float) num3) / 255f, 1f);
        }

        public static string UpdateActionTooltip(FsmStateAction action)
        {
            TooltipLookup.Remove(action);
            string tooltipAttribute = GetTooltipAttribute(action);
            if (!string.IsNullOrEmpty(action.Name))
            {
                tooltipAttribute = "Title: " + action.Name + "\nAction: " + NicifyVariableName(StripNamespace(action.GetType().ToString())) + "\n" + tooltipAttribute;
            }
            else
            {
                tooltipAttribute = "Action: " + NicifyVariableName(StripNamespace(action.GetType().ToString())) + "\n" + tooltipAttribute;
            }
            TooltipLookup.Add(action, tooltipAttribute);
            return tooltipAttribute;
        }

        public static List<string> ActionCategoryList
        {
            get
            {
                return actionCategoryList;
            }
        }

        public static List<string> ActionCategoryLookup
        {
            get
            {
                return actionCategoryLookup;
            }
        }

        public static List<System.Type> Actionslist
        {
            get
            {
                if ((actionsList == null) || (actionsList.Count == 0))
                {
                    BuildActionsList();
                }
                return actionsList;
            }
        }

        public static List<System.Type> ObjectTypeList
        {
            get
            {
                if (objectTypeList == null)
                {
                    BuildObjectTypeList();
                }
                return objectTypeList;
            }
        }

        public static List<string> ScriptList
        {
            get
            {
                if (scriptList == null)
                {
                    BuildScriptList();
                }
                return scriptList;
            }
        }
    }
}

